/**
 * Copyright 2017 区长
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.github.lizhangqu.coreprogress;

/**
 * Progress callback
 *
 * @author lizhangqu
 * @version V1.0
 * @since 2017-07-12 16:19
 */
public abstract class ProgressListener implements ProgressCallback {
    boolean started;
    long lastRefreshTime = 0L;
    long lastBytesWritten = 0L;
    /**
     * Minimum callback time 100ms，Avoid frequent callback.
     */
    int minTime = 100;

    /**
     * The progress changes. If the values of numBytes, totalBytes, and percent are -1,
     * the total size cannot be obtained.
     *
     * @param numBytes   Read/Write Size
     * @param totalBytes Total Size
     * @param percent    Percentage
     */
    public final void onProgressChanged(long numBytes, long totalBytes, float percent) {
        if (!started) {
            onProgressStart(totalBytes);
            started = true;
        }
        if (numBytes == -1 && totalBytes == -1 && percent == -1) {
            onProgressChanged(-1, -1, -1, -1);
            return;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastRefreshTime >= minTime || numBytes == totalBytes || percent >= 1F) {
            long intervalTime = (currentTime - lastRefreshTime);
            if (intervalTime == 0) {
                intervalTime += 1;
            }
            long updateBytes = numBytes - lastBytesWritten;
            final long networkSpeed = (updateBytes / intervalTime);
            onProgressChanged(numBytes, totalBytes, percent, networkSpeed);
            lastRefreshTime = System.currentTimeMillis();
            lastBytesWritten = numBytes;
        }
        if (numBytes == totalBytes || percent >= 1F) {
            onProgressFinish();
        }
    }

    /**
     * The progress changes. If the values of numBytes, totalBytes, percent, and speed are -1,
     * the total size cannot be obtained.
     *
     * @param numBytes   Read/Write Size
     * @param totalBytes Total Size
     * @param percent    Percentage
     * @param speed      speed bytes/ms
     */
    public abstract void onProgressChanged(long numBytes, long totalBytes, float percent, float speed);

    /**
     * Progress Start
     *
     * @param totalBytes Total Size
     */
    public void onProgressStart(long totalBytes) {}

    /**
     * Progress End
     */
    public void onProgressFinish() {}
}
